import hashlib
import json
import shutil
from pathlib import Path
from typing import Dict, List, Optional
from lxml import etree
import requests
from openai import OpenAI
from pprint import pprint


class DeepSeekCodeAnalyzer:
    def __init__(self):
        self.api_key = 'sk-b6eb6b5c93884e5aa2676e1e0d60d620'
        self.api_url = "https://api.deepseek.com/v1/"
        self.client = OpenAI(api_key=self.api_key, base_url=self.api_url)

    def analyze_html_file(self, html_file: str) -> Dict:
        """分析HTML文件中的所有代码片段"""
        with open(html_file, 'r', encoding='utf-8') as f:
            html = f.read()

        code_blocks = self._extract_code_blocks(html)
        self._analyze_code_with_deepseek(html)


    def _extract_code_blocks(self, html: str) -> List[str]:
        """使用BeautifulSoup提取所有<pre><code>内容"""
        tree = etree.HTML(html)
        code_blocks = []
        codes = tree.xpath('//pre')
        for code in codes:
            code_blocks.append(code.text)
        return code_blocks

    def _analyze_code_with_deepseek(self, html: str) -> Dict:
        """调用DeepSeek API分析代码语法"""
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }

        prompt = f"""作为ArkTS语言专家和应用开发专家，结果用中文回答，请检查{html}文中的代码片段是否有问题，包括语法问题和代码逻辑问题：
                ，不完整的代码需要根据前面给你提供的html源代码进行相应的判断。
                片段代码通过 xpath('//pre')获取即可。
                要求：
                1. 语法错误
                2. 永远为假的循环条件
                3. 未使用的变量
                4. 无法到达的代码
                5. 所有的代码都在html中，有些代码不完整需要结合html中的上下文进行判断

                返回JSON格式显示为中文：
                {{
                    "position": "[输出代码是第几段片段]",
                    "code":["输出代码片段"],
                    "result":["如果存在问题则输出Failed，如果没问题输出Pass"]
                    "is_complete": 布尔值,
                    "syntax_errors": ["问题描述"],
                    "missing_definitions": ["缺失的类/变量"],
                    "suggested_fixes": ["修复建议"]
                }}"""

        payload = {
            "model": "deepseek-chat",
            "messages": [{"role": "user", "content": prompt}],
            "max_tokens": 3000,
            "temperature": 0.2  # 降低随机性
        }

        response_stream = self.client.chat.completions.create(
            model="deepseek-chat",
            messages=[{"role": "user", "content": prompt}],
            # max_tokens=4096,  # 单次响应上限（可调整）
            stream=True  # 关键：启用流式获取
        )
        # 4. 逐块读取流式结果
        full_response = []
        for chunk in response_stream:
            chunk_text = chunk.choices[0].delta.content or ""
            print(chunk_text, end="", flush=True)  # 实时打印
            full_response.append(chunk_text)

    def _save_to_cache(self, key: str, data: Dict):
        """保存结果到缓存"""
        with open(self.cache_dir / f'{key}.json', 'w', encoding='utf-8')as f:
            json.dump(data, f, ensure_ascii=False, indent=2)

    def _generate_report(self, results: List[Dict]) -> Dict:
        """生成综合分析报告"""
        stats = {
            "total_snippets": len(results),
            "error_snippets": sum(1 for r in results if r.get("syntax_errors")),
            "missing_definitions": sum(len(r.get("missing_definitions", [])) for r in results)
        }

        return {
            "metadata": stats,
            "details": results,
            "summary": self._create_summary(results)
        }

    def _create_summary(self, results: List[Dict]) -> str:
        """生成Markdown格式摘要"""
        summary = ["# 代码分析报告", f"共分析 {len(results)} 个代码片段\n"]

        for res in results:
            summary.append(f"\n## {res['position']}")
            summary.append(f"```typescript\n{res.get('original_code', '')}\n```")

            if errors := res.get("syntax_errors"):
                summary.append("❌ **语法错误:**")
                summary.extend(f"- {e}" for e in errors)

            if missing := res.get("missing_definitions"):
                summary.append("🔍 **缺失定义:**")
                summary.extend(f"- {m}" for m in missing)

            if fixes := res.get("suggested_fixes"):
                summary.append("💡 **修复建议:**")
                summary.extend(f"- {f}" for f in fixes)

        return "\n".join(summary)

    def _generate_cache_key(self, code: str) -> str:
        """生成缓存文件名"""
        return hashlib.md5(code.encode()).hexdigest()

    def _load_from_cache(self, key: str) -> Optional[Dict]:
        cache_file = self.cache_dir / f'{key}.json'
        if cache_file.exists():
            with open(cache_file, 'r', encoding='utf-8')as f:
                return json.load(f)
        return None


if __name__ == '__main__':
    ds = DeepSeekCodeAnalyzer()
    ds.analyze_html_file('test.html')

